package com.live555.utils;

import android.view.SurfaceHolder;
import android.view.SurfaceView;

import com.live555.decoder.H264Decoder;
import com.live555.sava264.H264FileSaveCallBackManager;

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;

/**
 * 功能描述：创建surfaceView，配置解码器
 *
 * @author：ZC 创建时间：2018/6/26 10:57
 * 最后修改日期：
 */
public class VideoUtils {
    public static class LocalShow {
        public static boolean putH264DataFlag = true;
        public static H264Decoder sH264Decoder;
        private static SurfaceHolder.Callback callback;
        public static Thread camThread;
        public static boolean isRunning = false;

        public static void addView(final SurfaceView surfaceView) {
            if (surfaceView == null) {
                return;
            }

            isRunning = true;
            if (camThread == null) {
                camThread = new CamThread();
                camThread.start();
            }

            callback = new SurfaceHolder.Callback() {
                @Override
                public void surfaceCreated(SurfaceHolder holder) {
                    try {
                        if (sH264Decoder != null) {
                            sH264Decoder.DecoderClose();
                            sH264Decoder = null;
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                    }

                    if (holder != null) {
                        sH264Decoder = new H264Decoder(holder, "video/avc", 1280, 720, 1);
                    } else {
                        return;
                    }
                }

                @Override
                public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {

                }

                @Override
                public void surfaceDestroyed(SurfaceHolder holder) {
                }
            };

            surfaceView.getHolder().addCallback(callback);

            putH264DataFlag = true;
        }

        public static void removeView() {
            if (sH264Decoder != null) {
                sH264Decoder.DecoderClose();
                sH264Decoder = null;
            }
            callback = null;

            putH264DataFlag = false;

            isRunning = false;
            if (camThread != null) {
                camThread.interrupt();
                camThread = null;
            }
        }

        private static void putH264Data(byte[] bytes) {
            if (!putH264DataFlag) {
                return;
            }
            try {
                h264dataQueue.offer(bytes);
//                LogUtils.i("bytes", "" + ConvertUtils.bytesToHexFun3(bytes));
            } catch (Exception e) {
//                e.printStackTrace();
            }
        }

        /**
         * 解码线程
         */
        public static class CamThread extends Thread {
            @Override
            public void run() {
                super.run();
                while (isRunning) {
                    try {
                        c = h264dataQueue.poll();
                        if (c == null) {
                            Thread.sleep(50);
                            continue;
                        }
                        if (sH264Decoder != null) {
                            if (putH264DataFlag && !sH264Decoder.onFrame(c, 0, c.length)) {
                                Thread.sleep(1);
                            }
                        }
                    } catch (Exception e) {
//                        e.printStackTrace();
                    }
                }
                h264dataQueue.clear();
                c = null;
            }
        }

        static {
            h264dataQueue = new ArrayBlockingQueue<byte[]>(1000);
        }

        private static BlockingQueue<byte[]> h264dataQueue;
        private static byte[] c;
    }

    private static byte[] mPpsSps = new byte[0];
    //是否允许保存H264文件
    public static boolean isToSaveH264 = false;
    //h264文件的保存路径
    public static String h264CurrentFilePath = "";
    //第一帧存储了关键帧
    public static boolean startWithIFram = false;

    /**
     * 获取pps和sps、关键帧
     *
     * @param outData
     */
    public static void makeSpsPps(byte[] outData) {
        if ((outData[0] == 0 && outData[1] == 0 && outData[2] == 0 && outData[3] == 1 && (outData[4] & 0x1f) == 7)) {
            mPpsSps = outData;
        } else if ((outData[0] == 0 && outData[1] == 0 && outData[2] == 0 && outData[3] == 1 && (outData[4] & 0x1f) == 5)) {
            byte[] data = new byte[mPpsSps.length + outData.length];
            System.arraycopy(mPpsSps, 0, data, 0, mPpsSps.length);
            System.arraycopy(outData, 0, data, mPpsSps.length, outData.length);
            outData = data;
            if (isToSaveH264) {
                FileTools.writeFileToSDCard(outData, h264CurrentFilePath);
                startWithIFram = true;
            }
        }
        LocalShow.putH264Data(outData);
        if (startWithIFram) {
            H264FileSaveCallBackManager.getInstance().onH264FrameDataComeByUser(true, outData, h264CurrentFilePath);
        }
    }

//    public static boolean isIFrame(byte[] data) {
//        if (data == null || data.length < 5) {
//            return false;
//        }
//        if (data[0] == 0x0
//                && data[1] == 0x0
//                && data[2] == 0x0
//                && data[3] == 0x1
//                && data[4] == 0x67) {
//            return true;
//        }
//        byte nalu = data[4];
//        return ((nalu & 0x1F) == 5) ? true : false;
//    }
}
